home *** CD-ROM | disk | FTP | other *** search
/ SGI Developer Toolbox 6.1 / SGI Developer Toolbox 6.1 - Disc 4.iso / public / SciAn / src / ScianGarbageMan.c < prev    next >
C/C++ Source or Header  |  1994-08-01  |  10KB  |  484 lines

  1. #include "Scian.h"
  2. #include "ScianTypes.h"
  3. #include "ScianLists.h"
  4. #include "ScianIDs.h"
  5. #include "ScianGarbageMan.h"
  6. #include "ScianWindows.h"
  7. #include "ScianDialogs.h"
  8. #include "ScianNetObjects.h"
  9.  
  10. #define MARKED 1
  11. #define CLEARED 0
  12.  
  13. #define ISDELETED 69234269
  14.  
  15. #define IsDeleted(thing) ((thing) -> garbageFlag == ISDELETED)
  16.  
  17. int TrashDayFlag = 0;
  18. ObjPtr globalObjectList = NULLOBJ;
  19. GlobalReferenceListPtr globalReferenceList = (GlobalReferenceListPtr) 0;
  20. ObjPtr deletedList = NULLOBJ;
  21.  
  22. long int freedObjects = 0;
  23.  
  24. void InitMem()
  25. {
  26. #if MALLOPT
  27. /* HAK optimizing adjustments for the new malloc */
  28.     if (mallopt(M_MXFAST, 128))
  29.     {
  30.     struct mallinfo mi;
  31.  
  32.     fprintf(stderr, "Uh-oh! malloc'ed something before mallopt call!\n");
  33.     
  34.     mi = mallinfo();
  35.     fprintf(stderr,"arena=%d, ordblks=%d, smblks=%d, hblkhd=%d, hblks=%d\n",
  36.             mi.arena, mi.ordblks, mi.smblks, mi.hblkhd, mi.hblks);
  37.     fprintf(stderr,"usmblks=%d, fsmblks=%d, uordblks=%d, fordblks=%d, keepcost=%d\n",
  38.         mi.usmblks, mi.fsmblks, mi.uordblks, mi.fordblks, mi.keepcost);
  39.     }
  40. #endif
  41. }
  42.  
  43. void KillMem()
  44. {
  45. }
  46.  
  47. void AddToGlobalList(obj)
  48. ObjPtr obj;
  49. {
  50.     obj -> gNext = globalObjectList;
  51.     globalObjectList = obj;
  52. }
  53.  
  54. /* took rNext out of Obj since only a tiny percentage of objects use it. */
  55.  
  56. #if 0
  57. void AddToReferenceList(obj)
  58. ObjPtr obj;
  59. {
  60.     if (obj->refCount > 0)
  61.     {
  62.     ++(obj -> refCount);
  63.     }
  64.     else if (obj->refCount == 0)
  65.     {
  66.     obj -> rNext = globalReferenceList;
  67.     globalReferenceList = obj;
  68.     ++(obj -> refCount);
  69.     }
  70.     else
  71.     {
  72.     ReportError("AddToReferenceList", "found negative refCount!");
  73.     }
  74. }
  75.  
  76. #else
  77. void AddToReferenceList(obj)
  78. ObjPtr obj;
  79. {
  80.     GlobalReferenceListPtr temp;
  81.  
  82.     if (!obj)
  83.     return;
  84.  
  85.     temp = Alloc(sizeof(struct GlobalReferenceListStruct));
  86.     temp -> obj = obj;
  87.     temp -> next = globalReferenceList;
  88.     globalReferenceList = temp;
  89. }
  90. #endif
  91.  
  92. #if 0
  93. int RemoveFromReferenceList(obj)
  94. ObjPtr obj;
  95. {
  96.     ObjPtr *runner;
  97.  
  98.     if (!obj)
  99.     return true;
  100.  
  101.     if (!globalReferenceList)
  102.     return false;
  103.  
  104.     --(obj -> refCount);
  105.  
  106.     if (obj -> refCount < 0)
  107.     ReportError("RemoveFromReferenceList", "found negative refCount!");
  108.  
  109.     if (obj->refCount > 0)
  110.     {
  111.     return true;
  112.     }
  113.  
  114.     runner = &globalReferenceList;
  115.     while (((*runner) -> rNext) && *runner != obj )
  116.     {
  117.     runner = &((*runner) -> rNext);
  118.     }
  119.  
  120.     if (*runner == obj)
  121.     {
  122.     /* really removing the thing from the reference list this time! */
  123.     *runner = (*runner) -> rNext;
  124.     ++TrashDayFlag;
  125.     return true;
  126.     }
  127.     return false;
  128. }
  129. #else
  130. int RemoveFromReferenceList(obj)
  131. ObjPtr obj;
  132. {
  133.     GlobalReferenceListPtr *runner, temp;
  134.  
  135.     if (!obj)
  136.     return true;
  137.  
  138.     if (!globalReferenceList)
  139.     {
  140.     ReportError("RemoveFromReferenceList", "object not in global list");
  141.     return false;
  142.     }
  143.  
  144.     runner = &globalReferenceList;
  145.     while (((*runner) -> next) && (*runner) -> obj != obj)
  146.     {
  147.     runner = &((*runner) -> next);
  148.     }
  149.  
  150.     if ((*runner) -> obj == obj)
  151.     {
  152.     temp = *runner;
  153.     *runner = (*runner) -> next;    /* remove ref list node. */
  154.     Free (temp);
  155.     ++TrashDayFlag;        /* may have been last reference to obj */
  156.     return true;
  157.     }
  158.     else
  159.     {
  160.     ReportError("RemoveFromReferenceList", "object not in global list");
  161.         return false;
  162.     }
  163. }
  164. #endif
  165.  
  166. void MarkVarTree(nodep)
  167. VarsPtr        nodep;        /* pointer to node to delete */
  168. /* MarkVarTree:    frees space allocated to a var node and all its kids */
  169. {
  170.     if (!nodep) return;
  171.     MarkVarTree(nodep->left);
  172.     MarkVarTree(nodep->right);
  173.     MarkObject(nodep->value);
  174. }
  175.  
  176. ObjPtr MarkList(list)
  177. ObjPtr list;
  178. /*(trial) Disposes of the contents of list*/
  179. {
  180.     ThingListPtr runner;
  181.  
  182.     runner = LISTOF(list);
  183.  
  184.     while (runner)
  185.     {
  186.     MarkObject(runner -> thing);
  187.     runner = runner -> next;
  188.     }
  189.     return ObjTrue;
  190. }
  191.  
  192. /* Garbage collection routine that marks an object and all of
  193.  * its children, if it can find them...
  194.  */
  195. int MarkObject(thingp)
  196. ObjPtr thingp;
  197. {
  198.     FuncTyp marker;
  199.  
  200.     if (!thingp)
  201.     return;
  202.     if (thingp == (ObjPtr) NETSTUBFLAG)
  203.     {
  204.     /* this special case ought to be handled in MarkObjectArray */
  205.     return;
  206.     }
  207.  
  208.     if (IsDeleted(thingp))
  209.     {
  210.     sprintf(tempStr, "Hey! tried to mark something already deleted! 0x%lx", thingp);
  211.     ReportError("MarkObject", tempStr);
  212.     }
  213.     else if (thingp->garbageFlag != MARKED && thingp->garbageFlag != CLEARED)
  214.     {
  215.     sprintf(tempStr, "Invalid GarbageMan flag! 0x%lx.\n", thingp);
  216.     ReportError("MarkObject", tempStr);
  217.     }
  218.  
  219.     if (thingp->garbageFlag == MARKED)
  220.     {
  221.     return; /* hit something already marked */
  222.     }
  223.  
  224.     thingp->garbageFlag = MARKED;
  225.     Mark(thingp);
  226.     MarkVarTree(thingp->vars);
  227.     MarkObject(thingp->class);
  228. }
  229.  
  230. int CountReferenceList()
  231. {
  232.     int counter = 0;
  233.     GlobalReferenceListPtr runner;
  234.  
  235.     runner = globalReferenceList;
  236.     while (runner)
  237.     {
  238.     ++counter;
  239.     runner = runner -> next;
  240.     }
  241.     return counter;
  242. }
  243.  
  244. int CountObjectList()
  245. {
  246.     int counter = 0;
  247.     ObjPtr runner;
  248.  
  249.     runner = globalObjectList;
  250.     while (runner)
  251.     {
  252.     ++counter;
  253.     runner = runner -> gNext;
  254.     }
  255.     return counter;
  256. }
  257.  
  258. typedef struct dStruct {
  259.     ObjPtr thing;
  260.     struct dStruct *next;
  261. } dListNode, *dPtr;
  262.  
  263. dPtr deleteList = 0;
  264.  
  265. void TrashDay()
  266. {
  267.     ObjPtr *prunner, temp;
  268.     GlobalReferenceListPtr runner;
  269.     FuncTyp marker;
  270. #ifdef GCTIMES
  271.     struct tms foo, newfoo, newerfoo;
  272. #endif
  273. #if DISABLETRASHDAY
  274.     return;
  275. #endif
  276. #ifdef GCTIMES
  277.     times(&foo);
  278. #endif
  279.     TrashDayFlag = 0;
  280.  
  281.     runner = globalReferenceList;
  282.     while (runner)
  283.     {
  284.     MarkObject((runner) -> obj);
  285.     runner = runner -> next;
  286.     }
  287.  
  288. #ifdef GCTIMES
  289.     times(&newfoo);
  290.     fprintf(stderr, "marked all things, utime=%ld, stime=%ld\n",
  291.         newfoo.tms_utime - foo.tms_utime, newfoo.tms_stime - foo.tms_stime);
  292. #endif
  293.     /*all referenced things marked, traverse all things, and dooda rite t'ing*/
  294.     prunner = &globalObjectList;
  295.  
  296.     /* figuring out what happens here is left as an exercise for the reader */
  297.     while (*prunner)
  298.     {
  299.     if ( (*prunner) -> garbageFlag == MARKED)
  300.     {
  301.         (*prunner) -> garbageFlag = CLEARED;
  302.         prunner = & ((*prunner) -> gNext);
  303.     }
  304.     else if ( (*prunner) -> garbageFlag == CLEARED)
  305.     {
  306.         if (!IsPublished(*prunner))
  307.         {
  308.         temp = *prunner;
  309.         *prunner = (*prunner) -> gNext;
  310.         AddToDeleteList(temp);
  311.         }
  312.     }
  313.     else
  314.     {
  315.         /* What to do, what to do? */
  316.         sprintf(tempStr, "Illegal garbageFlag value! 0x%lx\n", *prunner);
  317.         ReportError("TrashDay", tempStr);
  318.         prunner = & ((*prunner) -> gNext);
  319.     }
  320.     }
  321.  
  322.     /* call cleanup on everything */
  323.     CleanupDeleteList();
  324.     /* free everything and their delete pointer nodes */
  325.     DeleteDeleteList();
  326.  
  327. #ifdef GCTIMES
  328.     times(&newerfoo);
  329.     fprintf(stderr, "done with cleanup, utime=%ld, stime=%ld\n",
  330.         newerfoo.tms_utime - newfoo.tms_utime, newerfoo.tms_stime - newfoo.tms_stime);
  331.     fprintf(stderr, "total time: utime = %ld, stime = %ld, tot=%ld\n",
  332.         newerfoo.tms_utime - foo.tms_utime, newerfoo.tms_stime - foo.tms_stime,
  333.         (newerfoo.tms_utime - foo.tms_utime) + (newerfoo.tms_stime - foo.tms_stime));
  334. #endif
  335. }
  336.  
  337. AddToDeleteList(ObjPtr obj)
  338. {
  339.     dPtr tmp;
  340.  
  341.     tmp = deleteList;
  342.     deleteList = Alloc(sizeof(dListNode));
  343.     deleteList -> thing = obj;
  344.     deleteList -> next = tmp;
  345. }
  346.  
  347. CleanupDeleteList()
  348. {
  349.     FuncTyp cleaner;
  350.     dPtr runner;
  351.     ObjPtr ret;
  352.  
  353.     runner = deleteList;
  354.  
  355.     while (runner)
  356.     {
  357.     cleaner = GetMethod(runner->thing, CLEANUP);
  358.     if (cleaner)
  359.     {
  360.         ret = (* cleaner) (runner->thing, NIL);
  361.         if (!IsTrue(ret))
  362.         {
  363.         sprintf(tempStr,"CLEANUP on object 0x%x reported an error!\n", runner->thing);
  364.         ReportError("CleanupDeleteList", tempStr);
  365.         sprintf(tempStr, "obj->flags == 0x%x\n", runner->thing->flags);
  366.         ReportError("CleanupDeleteList", tempStr);
  367.         }
  368.     }
  369.     runner = runner -> next;
  370.     }
  371. }
  372.  
  373. DeleteDeleteList()
  374. {
  375.     dPtr temp;
  376.  
  377.     while(deleteList)
  378.     {
  379.     if (IsList(deleteList->thing))
  380.     {
  381.         DeleteWithPrejudiceVarNode(deleteList->thing->vars);
  382.         DeleteMethodNode(deleteList->thing->methods);
  383.         DisposeListWithPersonalDislike(deleteList->thing);
  384.     }
  385.     else
  386.     {
  387.         DeleteWithPrejudiceVarNode(deleteList->thing->vars);
  388.         DeleteMethodNode(deleteList->thing->methods);
  389.         deleteList->thing -> garbageFlag = ISDELETED;
  390.         Free (deleteList->thing);
  391.         DecGlobalThingCount();
  392.     }
  393.     temp = deleteList -> next;
  394.     Free(deleteList);
  395.     deleteList = temp;
  396.     ++freedObjects;
  397.     }
  398. }
  399.  
  400. void DeleteWithPrejudiceVarNode(nodep)
  401. VarsPtr        nodep;        /* pointer to node to delete */
  402. /* DeleteVarNode:    frees space allocated to a var node and all its kids */
  403. {
  404.     if (!nodep) return;
  405.     DeleteWithPrejudiceVarNode(nodep->left);
  406.     DeleteWithPrejudiceVarNode(nodep->right);
  407.     Free(nodep);
  408. }
  409.  
  410. void DisposeListWithPersonalDislike(list)
  411. ObjPtr list;
  412. {
  413.     while (LISTOF(list))
  414.     {
  415.     ThingListPtr next;
  416.     next = LISTOF(list) -> next;
  417.     Free(LISTOF(list));
  418.     LISTOF(list) = next;
  419.     }
  420.     LISTOF(list) = 0;
  421.     list -> garbageFlag = ISDELETED;
  422.     Free(list);
  423.     DecGlobalThingCount();
  424. }
  425.  
  426. void DeleteWithPrejudice(obj)
  427. ObjPtr obj;
  428. {
  429.     FuncTyp cleaner;
  430.     ObjPtr ret;
  431.  
  432.     if (IsPublished(obj))
  433.     {
  434.     fprintf(stderr, "HEY! tried to delete published object!\n");
  435.     return;
  436.     }
  437.  
  438. #if 0
  439.     if (IsPublished(obj))
  440.     {
  441. #ifdef DEBUG
  442.     fprintf(stderr, "removing published object 0x%x\n", obj);
  443. #endif
  444.     UnPublishObject(obj);
  445.     return;
  446.     }
  447. #endif
  448.  
  449.     if (IsRemote(obj))
  450.     {
  451.     /* fprintf(stderr, "removing remote object 0x%x\n", obj); */
  452.     }
  453.  
  454.     cleaner = GetMethod(obj, CLEANUP);
  455.     if (cleaner)
  456.     {
  457.     ret = (* cleaner) (obj, NIL);
  458.     if (!IsTrue(ret))
  459.     {
  460.         sprintf(tempStr,"CLEANUP on object 0x%x reported an error!\n", obj);
  461.         ReportError("DeleteWithPrejudice", tempStr);
  462.         sprintf(tempStr, "obj->flags == 0x%x\n", obj->flags);
  463.         ReportError("DeleteWithPrejudice", tempStr);
  464.     }
  465.     }
  466.  
  467.     if (IsList(obj))
  468.     {
  469.     DeleteWithPrejudiceVarNode(obj->vars);
  470.     DeleteMethodNode(obj->methods);
  471.     DisposeListWithPersonalDislike(obj);
  472.     }
  473.     else
  474.     {
  475.     DeleteWithPrejudiceVarNode(obj->vars);
  476.     DeleteMethodNode(obj->methods);
  477.     obj -> garbageFlag = ISDELETED;
  478.     Free (obj);
  479.     DecGlobalThingCount();
  480.     }
  481.     ++freedObjects;
  482. }
  483.  
  484.